import os
from typing import List, TextIO, Dict

from bean.Constants import Constants


class BaseBuilder:
    output_map: Dict[str, str] = {
        "BaseMapper.txt": Constants.get_instance().MAPPERS_PATH,
        "DateTimePatternEnum.txt": Constants.get_instance().ENUM_PATH,
        "DateUtils.txt": Constants.get_instance().UTILS_PATH,
        "BaseQuery.txt": Constants.get_instance().PARAM_PATH,
        "PageSize.txt": Constants.get_instance().ENUM_PATH,
        "SimplePage.txt": Constants.get_instance().PARAM_PATH,
        "PaginationResultVO.txt": Constants.get_instance().VO_PATH,
        "BusinessException.txt": Constants.get_instance().EXCEPTION_PATH,
        "ResponseCodeEnum.txt": Constants.get_instance().ENUM_PATH,
        "ResponseVO.txt": Constants.get_instance().VO_PATH,
        "ABaseController.txt": Constants.get_instance().CONTROLLER_PATH,
        "AGlobalExceptionHandlerController.txt": Constants.get_instance().CONTROLLER_PATH
    }

    import_package_map: Dict[str, List[str]] = {
        "SimplePage.txt": [
            Constants.get_instance().PACKAGE_ENUM + "." + "PageSize"
        ],
        "BusinessException.txt": [
            Constants.get_instance().PACKAGE_ENUM + "." + "ResponseCodeEnum"
        ],
        "ABaseController.txt": [
            Constants.get_instance().PACKAGE_ENUM + "." + "ResponseCodeEnum",
            Constants.get_instance().PACKAGE_VO + "." + "ResponseVO"
        ],
        "AGlobalExceptionHandlerController.txt": [
            Constants.get_instance().PACKAGE_ENUM + "." + "ResponseCodeEnum",
            Constants.get_instance().PACKAGE_VO + "." + "ResponseVO",
            Constants.get_instance().PACKAGE_EXCEPTION + "." + "BusinessException"
        ]
    }

    @staticmethod
    def execute_build() -> None:
        template_names = os.listdir(Constants.get_instance().TEMPLATES_PATH)
        for i in template_names:
            j = i.split(".")
            if j[-1] != "txt" or j is None:
                continue
            else:
                BaseBuilder.build_templates(i)

    @staticmethod
    def build_templates(template_name: str) -> None:
        if template_name not in BaseBuilder.output_map.keys():
            raise Exception(f"{template_name}不在映射中")
        output_path = BaseBuilder.output_map[template_name]
        output_package = Constants.get_instance().get_package_by_path(output_path)
        template_file_path = Constants.get_instance().TEMPLATES_PATH + template_name
        package_name = f"package {output_package};"
        with open(template_file_path, "r", encoding="utf-8") as f:
            template = f.read()
        if not os.path.exists(output_path):
            os.makedirs(output_path)

        with open(output_path + template_name.split(".")[0] + ".java", "w", encoding="utf-8") as f:
            f.write(package_name)
            f.write("\n")
            if template_name in BaseBuilder.import_package_map.keys():
                f.write("\n")
                BaseBuilder.build_import_classes(f, BaseBuilder.import_package_map[template_name])
            f.write("\n")
            f.write(template)

    @staticmethod
    def build_import_classes(file_pointer: TextIO, package_lst: List[str]) -> None:
        if package_lst is []:
            return
        else:
            for i in package_lst:
                file_pointer.write(f"import {i};")
                file_pointer.write("\n")

    @staticmethod
    def connect_package(package: str, java_name: str) -> str:
        return package + "." + java_name


if __name__ == "__main__":
    BaseBuilder.execute_build()
